import inspect
from datetime import datetime
from typing import Literal
from common.base.base_api import BaseApi
from .schemas.ad_ul_dl import AdUlDl
from .schemas.full_unit_configuration import FullUnitConfiguration
from services.server_integration.schemas.calibrate_status import CalibrateMessage
from .schemas.alarms import Alarm, AlarmDescription
from .schemas.technical_status import TechnicalStatus
from .schemas.alarms_request import AlarmsRequest
from .schemas.ac_magic_numbers import ACMagicNumbers
from .schemas.alarms_response_configuration import AlarmResponseConfiguration
from .schemas.alarms import OldestNewestAlarmsDate
from settings import settings
from .schemas.cities_timezone import TimezonesRequest, CityTimezone, CityByTimezoneRequest
from services.new_services.new_server_integration.schemas.zcalibration import ZCalibrationTelemetry, ZCalibrationInfo,\
    ZCalibrationStatus, ZCalibrationDevice
from services.server_integration.schemas.alarms_response_configuration import AlarmResponseConfiguration


class ServerIntegrationApi(BaseApi):
    __slots__ = []

    def __init__(self):
        super(ServerIntegrationApi, self).__init__(request_queue_uuid=settings.SERVER_INTEGRATION_REQUEST_QUEUE)

    async def set_production_state(self, state: bool):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'state': state})

    async def get_production_state(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def set_rtr_normal_vswr(self, index: int, vswr: float):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'index': index, 'vswr': vswr})

    async def get_rtr_normal_vswr(self, index: int) -> float:
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'index': index})

    async def calibrate_rtr_vswr(self, index: int) -> float | None:
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'index': index})

    async def set_full_configuration(self, config: FullUnitConfiguration, user_role: str = 'user') -> bool:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {
                'config': config,
                'user_role': user_role
            },
            timeout=11 * 60
        )

    async def get_full_configuration(self) -> FullUnitConfiguration:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            handle_result=lambda result: FullUnitConfiguration(**result)
        )

    async def start_calibrate(self) -> bool:
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, timeout=25 * 60)

    async def special_calibrate(
        self,
        device: Literal['RM0', 'RM1', 'SM0', 'SM1', 'SM2', 'SM3', 'BS0', 'BS1', 'BS2', 'BS3'],
        power: float
    ) -> bool:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'device': device, 'power': power},
            timeout=25 * 60
        )

    async def set_ac_magic_numbers(
        self,
        device: Literal['RM0', 'RM1', 'SM0', 'SM1', 'SM2', 'SM3', 'BS0', 'BS1', 'BS2', 'BS3'],
        correct_number: float, real_power: float, power: float
    ):
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {
                'device': device,
                'correct_number': correct_number,
                'real_power': real_power,
                'power': power
            }
        )

    async def get_ac_magic_numbers(
        self,
        device: Literal['RM0', 'RM1', 'SM0', 'SM1', 'SM2', 'SM3', 'BS0', 'BS1', 'BS2', 'BS3']
    ) -> ACMagicNumbers:
        result = await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'device': device},
            handle_result=lambda r: ACMagicNumbers(**r)
        )
        return result

    async def get_current_alarms(self, request: AlarmsRequest, user_role: str):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {
            'request': request,
            'user_role': user_role
        })

    async def get_newest_oldest_alarms_date(self, user_role: str) -> OldestNewestAlarmsDate:
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'user_role': user_role})

    async def get_alarms_log(self, request: AlarmsRequest, user_role: str):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {
            'request': request,
            'user_role': user_role
        })

    async def get_technical_status(self) -> TechnicalStatus:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            handle_result=lambda result: TechnicalStatus(**result)
        )

    async def raise_info(self, name: str, value: float | int | bool = 0.0, end_value: float | int | bool = None):
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {
                'name': name,
                "value": value,
                'end_value': end_value
            }
        )

    async def raise_alarm(self, name: str, state: bool = True, value: float | int | bool = 0.0) -> bool:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {
                'name': name,
                "state": state,
                'value': value
            }
        )

    async def load_alarms_descriptions(self) -> list[AlarmDescription]:
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def get_cities_timezones(self, request: TimezonesRequest):
        res = await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'request': request})
        return res

    async def get_city_by_timezone(self, request: CityByTimezoneRequest):
        res = await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'request': request})
        return res

    async def reboot_motherboard(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def reboot_power(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)
    
    async def get_server_ip(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def get_server_proxy_ip(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def get_serial_number(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def get_cviya_list(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def clear_alarms(self):
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def set_calibrate_status(self, msg: CalibrateMessage):
        res = await self.send_rpc_request_message(inspect.currentframe().f_code.co_name, {'msg': msg})
        return res

    async def get_timezone(self) -> int:
        return await self.send_rpc_request_message(inspect.currentframe().f_code.co_name)

    async def zcalibration_calibrate(self, device: int, target_power: float) -> ZCalibrationStatus:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'device': device, 'target_power': target_power}
        )

    async def zcalibration_telemetry(self, device: int) -> ZCalibrationTelemetry:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'device': device},
            handle_result=lambda result: ZCalibrationTelemetry(**result)
        )

    async def zcalibration_info(self, device: int) -> ZCalibrationInfo:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'device': device},
            handle_result=lambda result: ZCalibrationInfo(**result)
        )

    async def zcalibration_save(self, device: int, info: ZCalibrationInfo):
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'device': device, 'info': info}
        )

    async def digital_tune_all(self):
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
        )

    async def get_ad_ul_dl(self) -> AdUlDl:
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            handle_result=lambda result: AdUlDl(**result)
        )

    async def set_gps_position(self, position: str):
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'position': position}
        )

    async def set_current_time(self, current_time: int):
        return await self.send_rpc_request_message(
            inspect.currentframe().f_code.co_name,
            {'current_time': current_time}
        )

